<?php
namespace app\providers\command;

use think\facade\Log;
use think\facade\Cache;
use think\console\Input;
use think\console\Output;
use think\console\Command;
use app\resources\model\Nodes;
use think\console\input\Option;

// php think client

class WebsocketCommand extends Command
{

    protected function configure()
    {
        // 指令配置
        $this->setName('client');
        // 设置描述
        $this->setDescription('链接websocker');
        // 添加选项
        $this->addOption('hort', null, Option::VALUE_OPTIONAL, '地址');
    }

    protected function execute(Input $input, Output $output)
    {
        $ssh = Nodes::getSecretKey();
        $hort = "ws://182.92.105.25:8001//ws?action=system&ssh=$ssh";
        Cache::set('WebsocketCommandHort',$hort);
        try {
            dump('开始链接');
            $client = new \WebSocket\Client($hort,[
                'filter'        => ['text', 'binary'],
                'fragment_size' => 10000,
                'timeout'       => 30
            ]);
            $client->receive();
            dump('链接成功');
            while (true) {
                try {
                    $msg = $client->receive();
                    if (strstr($msg, "}")) {
                        if ($message = json_decode($msg, true)) {
                            $type = $message['type'] ?? '';
                            $body = base64_decode($message['body'] ?? '');
                            dump($body);
                            // 容器内
                            if ($type == 'cmd' || $type == 'cmd:host') {
                                $out = '';
                                try {
                                    if ($type == 'cmd:host') {
                                        exec("nsenter -m -u -i -n -p  -t 1 sh -c '$body'", $out, $ret);
                                    } else {
                                        exec($body, $out, $ret);
                                    }
                                    Log::info('执行cmd指令成功:');
                                    Log::info($message);
                                } catch (\Exception $e) {
                                    Log::error('执行cmd指令错误:');
                                    Log::error($body);
                                    Log::error($e);
                                }
                                $client->send(json_encode([
                                    'type' => 'cmd',
                                    'out' => $out,
                                    'message' => $message,
                                ], true));
                            }
                        } else {
                            Log::info('json格式错误:' . $msg);
                        }
                    }
                } catch (\WebSocket\ConnectionException $e) {
                    throw new \think\Exception($e->getMessage());
                }
            }
        } catch (\Exception $e) {
            sleep(3);
            $this->execute($input,$output);
        }
    }
}



